/*
	This file is part of the OdinMS Maple Story Server
    Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> 
                       Matthias Butz <matze@odinms.de>
                       Jan Christian Meyer <vimes@odinms.de>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
    as published by the Free Software Foundation. You may not use, modify
    or distribute this program under any other version of the
    GNU Affero General Public License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package client.messages.commands;

import java.util.Arrays;

import client.MapleCharacterUtil;
import client.MapleClient;
import client.MapleStat;
import client.PlayerStats;
import client.messages.Command;
import client.messages.CommandDefinition;
import client.messages.IllegalCommandSyntaxException;
import java.rmi.RemoteException;
import scripting.NPCScriptManager;
import server.life.MapleMonster;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import tools.MaplePacketCreator;
import tools.StringUtil;

public class PlayerCommand implements Command {

    @Override
    public void execute(MapleClient c, String[] splitted) throws Exception, IllegalCommandSyntaxException {

	if (splitted[0].equals("@str")) {
	    int str = Integer.parseInt(splitted[1]);
	    final PlayerStats stat = c.getPlayer().getStat();

	    if (stat.getStr() + str > c.getPlayer().getMaxStats() || c.getPlayer().getRemainingAp() < str || c.getPlayer().getRemainingAp() < 0 || str < 0) {
		c.getPlayer().dropMessage(5, "An error occured.");
	    } else {
		stat.setStr(stat.getStr() + str);
		c.getPlayer().setRemainingAp(c.getPlayer().getRemainingAp() - str);
		c.getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, c.getPlayer().getRemainingAp());
		c.getPlayer().updateSingleStat(MapleStat.STR, stat.getStr());
	    }
	} else if (splitted[0].equals("@int")) {
	    int int_ = Integer.parseInt(splitted[1]);
	    final PlayerStats stat = c.getPlayer().getStat();

	    if (stat.getInt() + int_ > c.getPlayer().getMaxStats() || c.getPlayer().getRemainingAp() < int_ || c.getPlayer().getRemainingAp() < 0 || int_ < 0) {
		c.getPlayer().dropMessage(5, "An error occured.");
	    } else {
		stat.setInt(stat.getInt() + int_);
		c.getPlayer().setRemainingAp(c.getPlayer().getRemainingAp() - int_);
		c.getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, c.getPlayer().getRemainingAp());
		c.getPlayer().updateSingleStat(MapleStat.INT, stat.getInt());
	    }
	} else if (splitted[0].equals("@dex")) {
	    int dex = Integer.parseInt(splitted[1]);
	    final PlayerStats stat = c.getPlayer().getStat();

	    if (stat.getDex() + dex > c.getPlayer().getMaxStats() || c.getPlayer().getRemainingAp() < dex || c.getPlayer().getRemainingAp() < 0 || dex < 0) {
		c.getPlayer().dropMessage(5, "An error occured.");
	    } else {
		stat.setDex(stat.getDex() + dex);
		c.getPlayer().setRemainingAp(c.getPlayer().getRemainingAp() - dex);
		c.getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, c.getPlayer().getRemainingAp());
		c.getPlayer().updateSingleStat(MapleStat.DEX, stat.getDex());
	    }
	} else if (splitted[0].equals("@luk")) {
	    int luk = Integer.parseInt(splitted[1]);
	    final PlayerStats stat = c.getPlayer().getStat();

	    if (stat.getLuk() + luk > c.getPlayer().getMaxStats() || c.getPlayer().getRemainingAp() < luk || c.getPlayer().getRemainingAp() < 0 || luk < 0) {
		c.getPlayer().dropMessage(5, "An error occured.");
	    } else {
		stat.setLuk(stat.getLuk() + luk);
		c.getPlayer().setRemainingAp(c.getPlayer().getRemainingAp() - luk);
		c.getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, c.getPlayer().getRemainingAp());
		c.getPlayer().updateSingleStat(MapleStat.LUK, stat.getLuk());
	    }

	} else if (splitted[0].equals("@gmlist")) {
	    c.getPlayer().dropMessage(5, "GameMaster list : Marat, ");

	} else if (splitted[0].equals("@onlineplayer")) {
	    c.getPlayer().dropMessage(6, "Characters connected to channel " + c.getChannel() + ":");
	    c.getPlayer().dropMessage(6, c.getChannelServer().getPlayerStorage().getOnlinePlayers(false));

	} else if (splitted[0].equals("@mobdebug")) {
	    MapleMonster mob;
	    for (final MapleMapObject monstermo : c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), 250000, Arrays.asList(MapleMapObjectType.MONSTER))) {
		mob = (MapleMonster) monstermo;
		c.getPlayer().dropMessage(6, "Monster " + mob.toString());
	    }
	} else if (splitted[0].equals("@dmg")) {
		c.getPlayer().setOnDMG(!c.getPlayer().isOnDMG());
		c.getPlayer().dropMessage(6, "Damage displays set to " + c.getPlayer().isOnDMG());
	} else if (splitted[0].equals("@npc")) {
	    NPCScriptManager.getInstance().start(c, 1052013);
        } else if (splitted[0].equals("@maxskills")) {
	    NPCScriptManager.getInstance().start(c, 9010009);
	} else if (splitted[0].equals("@dropcash")) {

		NPCScriptManager.getInstance().start(c, 9010017);
	} else if (splitted[0].equals("@callgm")) {
		if (c.getPlayer().getCSPoints(1) < 500) {
			c.getPlayer().dropMessage(6, "You need 500 cash.");
			return;
		}
		c.getPlayer().modifyCSPoints(1, -500, true);
		final StringBuilder msg = new StringBuilder("[GM Call] ");
		msg.append(c.getPlayer().getName());
		msg.append(" has requested for help : ");
		msg.append(StringUtil.joinStringFrom(splitted, 1));
		try {
			c.getChannelServer().getWorldInterface().broadcastGMMessage(MaplePacketCreator.serverNotice(5, msg.toString()).getBytes());
		} catch(RemoteException e) {
			c.getChannelServer().reconnectWorld();
		}
	} else if (splitted[0].equals("@dispose")) {
	    NPCScriptManager.getInstance().dispose(c);

	} else if (splitted[0].equals("@ea")) {
	    c.getSession().write(MaplePacketCreator.enableActions());

	} else if (splitted[0].equals("@tsmega")) {
	    c.getPlayer().setSmega();

	} else if (splitted[0].equals("@changesecondpass")) {
	    if (splitted[2].equals(splitted[3])) {
		if (splitted[2].length() < 4 || splitted[2].length() > 16) {
		    c.getPlayer().dropMessage(5, "Your new password must not be length of below 4 or above 16.");
		} else {
		    final int output = MapleCharacterUtil.Change_SecondPassword(c.getAccID(), splitted[1], splitted[2]);

		    if (output == -2 || output == -1) {
			c.getPlayer().dropMessage(1, "An unknown error occured");
		    } else if (output == 0) {
			c.getPlayer().dropMessage(1, "You do not have a second password set currently, please set one at character selection.");
		    } else if (output == 1) {
			c.getPlayer().dropMessage(1, "The old password which you have inputted is invalid.");
		    } else if (output == 2) {
			c.getPlayer().dropMessage(1, "Password changed successfully!");
		    }
		}
	    } else {
		c.getPlayer().dropMessage(1, "Please confirm your new password again.");
	    }
	} else if (splitted[0].equals("@help")) {
	    c.getPlayer().dropMessage(5, "List of commands :");
	    c.getPlayer().dropMessage(5, "@str, @dex, @int, @luk <amount to add>");
	    c.getPlayer().dropMessage(5, "@callgm < send GM message, cost 500 cash >");
	    c.getPlayer().dropMessage(5, "@gmlist < List out names of GM >");
	    c.getPlayer().dropMessage(5, "@dmg < List true damage >");
	    c.getPlayer().dropMessage(5, "@onlineplayer < List out everyone online >");
	    c.getPlayer().dropMessage(5, "@mobdebug < Gives information on the monster, like its HP and etc. >");
	    c.getPlayer().dropMessage(5, "@changesecondpass - Change second password, @changesecondpass <current Password> <new password> <Confirm new password> ");
	    c.getPlayer().dropMessage(5, "@npc < Opens index NPC>");
	    c.getPlayer().dropMessage(5, "@dropcash < Opens dropcash NPC>");
	    c.getPlayer().dropMessage(5, "@dispose < Dispose if you are unable to talk to NPC >");
	    c.getPlayer().dropMessage(5, "@tsmega < Toggle super megaphone on/off >");
	    c.getPlayer().dropMessage(5, "@ea < If you are unable to attack >");
	}
    }

    @Override
    public CommandDefinition[] getDefinition() {
	return new CommandDefinition[]{
		    new CommandDefinition("onlineplayer", "", "List the players online.", 0),
		    new CommandDefinition("mobdebug", "", "Debug information on the closest monster.", 0),
		    new CommandDefinition("str", "", "Add your stats in one go.", 0),
		    new CommandDefinition("int", "", "Add your stats in one go.", 0),
		    new CommandDefinition("dex", "", "Add your stats in one go.", 0),
		    new CommandDefinition("luk", "", "Add your stats in one go.", 0),
		    new CommandDefinition("maxskills", "", "max all ur skill", 0),
                    new CommandDefinition("ea", "", "stuck", 0),
		    new CommandDefinition("dropcash", "", "stuck", 0),
		    new CommandDefinition("dmg", "", "stuck", 0),
		    new CommandDefinition("callgm", "", "stuck", 0),
		    new CommandDefinition("gmlist", "", "Current GMs", 0),
		    new CommandDefinition("tsmega", "", "Enable / Disable smega", 0),
		    new CommandDefinition("npc", "", "Npc index", 0),
		    new CommandDefinition("changesecondpass", "", "Change second password", 0),
		    new CommandDefinition("dispose", "", "Dispose if you are unable to talk to NPC", 0),
		    new CommandDefinition("help", "", "Lists player commands.", 0),};
    }
}
